package StudyCode.summary.zipfile;

import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

/**
 * 版权所有 科技与人文(www.tah1986.com)
 */
public class UnzipsTheSpecifiedZipFile {
	public static void unzip(String zipFilename, String destDirname)
			throws IOException {
		final Path destDir = Paths.get(destDirname);
		if (Files.notExists(destDir)) {
			System.out.println(destDir + " 不存在，创建中...");
			Files.createDirectories(destDir);
		}

		try (FileSystem zipFileSystem = createZipFileSystem(zipFilename,
				false)) {
			final Path root = zipFileSystem.getPath("/");

			Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
				@Override
				public FileVisitResult visitFile(Path file,
				                                 BasicFileAttributes attrs) throws IOException {
					final Path destFile = Paths.get(destDir.toString(),
							file.toString());
					System.out.printf("解压文件 %s to %s\n", file,
							destFile);
					Files.copy(file, destFile,
							StandardCopyOption.REPLACE_EXISTING);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult preVisitDirectory(Path dir,
				                                         BasicFileAttributes attrs) throws IOException {
					final Path dirToCreate = Paths.get(destDir.toString(),
							dir.toString());
					if (Files.notExists(dirToCreate)) {
						System.out.printf("创建目录 %s\n",
								dirToCreate);
						Files.createDirectory(dirToCreate);
					}
					return FileVisitResult.CONTINUE;
				}
			});
		}
	}


	public static FileSystem createZipFileSystem(String zipFilename,
	                                             boolean create) throws IOException {
		final Path path = Paths.get(zipFilename);
		final URI uri = URI.create("jar:file:" + path.toUri().getPath());
		final Map<String, String> env = new HashMap<>();
		if (create) {
			env.put("create", "true");
		}
		return FileSystems.newFileSystem(uri, env);
	}


	public static void create(String zipFilename, String... filenames)
			throws IOException {
		try (FileSystem zipFileSystem = createZipFileSystem(zipFilename,
				true)) {
			final Path root = zipFileSystem.getPath("/");

			for (String filename : filenames) {
				final Path src = Paths.get(filename);

				if (!Files.isDirectory(src)) {
					final Path dest = zipFileSystem.getPath(
							root.toString(), src.toString());
					final Path parent = dest.getParent();
					if (Files.notExists(parent)) {
						System.out
								.printf("创建目录 %s\n", parent);
						Files.createDirectories(parent);
					}
					Files.copy(src, dest,
							StandardCopyOption.REPLACE_EXISTING);
				} else {
					Files.walkFileTree(src, new SimpleFileVisitor<Path>() {
						@Override
						public FileVisitResult visitFile(Path file,
						                                 BasicFileAttributes attrs)
								throws IOException {
							final Path dest = zipFileSystem.getPath(
									root.toString(), file.toString());
							Files.copy(file, dest,
									StandardCopyOption.REPLACE_EXISTING);
							return FileVisitResult.CONTINUE;
						}

						@Override
						public FileVisitResult preVisitDirectory(Path dir,
						                                         BasicFileAttributes attrs)
								throws IOException {
							final Path dirToCreate = zipFileSystem.getPath(
									root.toString(), dir.toString());
							if (Files.notExists(dirToCreate)) {
								System.out.printf(
										"创建目录 %s\n",
										dirToCreate);
								Files.createDirectories(dirToCreate);
							}
							return FileVisitResult.CONTINUE;
						}
					});
				}
			}
		}
	}
}
